﻿using AutoMapper;
using InitQ.Cache;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;
using SkiaSharp;
using Smart.Admin.Domain.Common;
using Smart.Admin.Domain.Model.Config;
using Smart.Admin.Domain.Model.Const;
using Smart.Admin.Domain.Model.Entity;
using Smart.Admin.Domain.Model.Enum;
using Smart.Admin.Domain.Model.Request.Account;
using Smart.Admin.Domain.Model.Request.Department;
using Smart.Admin.Domain.Model.Request.Employee;
using Smart.Admin.Domain.Model.Request.Role;
using Smart.Admin.Domain.Model.Response;
using Smart.Admin.Domain.Model.Response.Account;
using Smart.Admin.Domain.Model.Response.Department;
using Smart.Admin.Domain.Model.Response.Employee;
using Smart.Admin.Domain.Model.Response.Menu;
using Smart.Admin.Domain.Model.Response.Role;
using Smart.Admin.Domain.Repository;
using StackExchange.Redis;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;

namespace Smart.Admin.Domain.Service
{
    /// <summary>
    /// 角色服务
    /// </summary>
    public class RoleService : EmployeeExtensions
    {
        private readonly SmartAdminDbContext _context;
        private readonly ICacheService _redisService;
        private readonly IOptions<JwtOptions> _options;
        private readonly IMapper _mapper;
        public RoleService(SmartAdminDbContext context, ICacheService redisService, IOptions<JwtOptions> options, IMapper mapper)
        {
            _context = context;
            _redisService = redisService;
            _options = options;
            _mapper = mapper;
        }


        /// <summary>
        /// 获取全部角色
        /// </summary>
        /// <returns></returns>
        public async Task<JsonResponse<List<GetAllRoleResponse>>> GetAllRole() 
        {
            try
            {
                var query =  from role in _context.Role
                             orderby role.Id descending
                             select new GetAllRoleResponse() 
                             {
                                 Remark = role.Remark,
                                 RoleId=role.Id,
                                 RoleCode=role.RoleCode,
                                 RoleName=role.RoleName
                             };
                            
                var response = await query.ToListAsync();
                return JsonResult.Success(response);
            }
            catch (Exception ex)
            {
                return JsonResult.Error<List<GetAllRoleResponse>>(message: "系统错误");
            }
        }



        /// <summary>
        /// 获取角色选中的菜单(树形结构)
        /// </summary>
        /// <returns></returns>
        public async Task<JsonResponse<GetRoleSelectedMenuResponse>> GetRoleSelectedMenu(long roleId)
        {
            try
            {
                //查询全部菜单
                var query = from menu in _context.Menu
                            where menu.DeletedFlag == false && menu.DisabledFlag == false && menu.VisibleFlag
                            orderby menu.Sort
                            select new RoleSelectedMenuDto()
                            {
                                MenuId = menu.Id,
                                ContextMenuId = menu.ContextMenuId,
                                MenuName = menu.MenuName,
                                MenuType = menu.MenuType,
                                ParentId = menu.ParentId,
                                Sort = menu.Sort,
                            };

                var list = await query.ToListAsync();
                var menuTreeList = list.Where(m => m.ParentId == 0).ToList() ?? new List<RoleSelectedMenuDto>();
                for (int i = 0; i < menuTreeList.Count; i++)
                {
                    menuTreeList[i] = BuildTreeMenu(list, menuTreeList[i]);
                }

                //查询角色菜单
                var selectedMenuId = await _context.RoleMenu.AsNoTracking().Where(p => p.RoleId == roleId).Select(m => m.MenuId).ToListAsync();
                var response = new GetRoleSelectedMenuResponse() 
                {
                    RoleId = roleId,
                    MenuTreeList = menuTreeList,
                    SelectedMenuId = selectedMenuId
                };
                return JsonResult.Success(response);
            }
            catch (Exception ex)
            {
                return JsonResult.Error<GetRoleSelectedMenuResponse>(message: "系统错误");
            }
        }



        /// <summary>
        /// 修改角色关联菜单
        /// </summary>
        /// <returns></returns>
        public async Task<JsonResponse> UpdateRoleMenu(UpdateRoleMenuRequest request)
        {
            try
            {
                var roleMenu = await _context.RoleMenu.AsNoTracking().Where(m => m.RoleId == request.RoleId).ToListAsync();
                if (roleMenu.Count > 0) 
                {
                    _context.RoleMenu.RemoveRange(roleMenu);
                }
                roleMenu = new List<RoleMenuEntity>();
                var dt = DateTime.Now;
                foreach (var menuId in request.MenuIdList) 
                {
                    roleMenu.Add(new RoleMenuEntity() 
                    {
                        CreateTime = dt,
                        MenuId = menuId,
                        RoleId=request.RoleId,
                        UpdateTime = dt,
                    });
                }
                await _context.RoleMenu.AddRangeAsync(roleMenu);
                await _context.SaveChangesAsync();
                return JsonResult.Success();
            }
            catch (Exception ex)
            {
                return JsonResult.Error(message: "系统错误");
            }
        }

        /// <summary>
        /// 创建角色
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public async Task<JsonResponse> CreateRole(CreateRoleRequest request)
        {
            try
            {
                var bl = await _context.Role.AnyAsync(m => m.RoleCode == request.RoleCode);
                if (bl) return JsonResult.Error(message: "角色编码已存在");
                var model = _mapper.Map<RoleEntity>(request);
                model.CreateTime = DateTime.Now;
                model.UpdateTime = model.CreateTime;
                await _context.Role.AddAsync(model);
                await _context.SaveChangesAsync();
                return JsonResult.Success();
            }
            catch (Exception ex)
            {
                return JsonResult.Error(message: "系统错误");
            }
        }


        /// <summary>
        /// 修改角色
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public async Task<JsonResponse> UpdateRole(UpdateRoleRequest request)
        {
            try
            {
                var model = await _context.Role.FirstOrDefaultAsync(m => m.Id == request.RoleId);
                if (model == null) return JsonResult.Error(message: "数据不存在");
                var bl = await _context.Role.AnyAsync(m => m.RoleCode == request.RoleCode && m.Id != request.RoleId);
                if (bl) return JsonResult.Error(message: "角色编码已存在");
                model.RoleName = request.RoleName;
                model.RoleCode = request.RoleCode;
                model.Remark = request.Remark;
                model.UpdateTime = DateTime.Now;
                _context.Role.Update(model);
                await _context.SaveChangesAsync();
                return JsonResult.Success();
            }
            catch (Exception ex)
            {
                return JsonResult.Error(message: "系统错误");
            }
        }

        /// <summary>
        /// 删除角色
        /// </summary>
        /// <param name="roleId"></param>
        /// <returns></returns>
        public async Task<JsonResponse> DeleteRole(long roleId)
        {
            try
            {
                var model = await _context.Role.FirstOrDefaultAsync(m => m.Id == roleId);
                if (model != null)
                {
                    //判断是否存在员工
                    var bl = await _context.RoleEmployee.AnyAsync(m => m.RoleId == roleId);
                    if (bl) return JsonResult.Error(message: "该角色正在被员工使用,请先修改员工角色");
                    //移除该角色关联的菜单
                    var roleMenu = await _context.RoleMenu.AsNoTracking().Where(m=>m.RoleId == roleId).ToListAsync();
                    if (roleMenu.Count > 0) 
                    {
                        _context.RoleMenu.RemoveRange(roleMenu);
                    }
                    _context.Role.Remove(model);
                    await _context.SaveChangesAsync();
                }
                return JsonResult.Success();
            }
            catch (Exception ex)
            {
                return JsonResult.Error(message: "系统错误");
            }
        }



        /// <summary>
        /// 角色添加员工
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public async Task<JsonResponse> AddRoleEmployee(AddRoleEmployeeRequest request)
        {
            try
            {
                if(request == null || request.EmployeeIdList == null || request.EmployeeIdList.Count()==0) return JsonResult.Error(message: "参数错误");

                var roleEmployee = await _context.RoleEmployee.Where(m => m.RoleId == request.RoleId && request.EmployeeIdList.Contains(m.EmployeeId)).ToListAsync();
                var list = new List<RoleEmployeeEntity>();
                var dt = DateTime.Now;
                foreach (var item in request.EmployeeIdList)
                {
                    if (!roleEmployee.Select(m => m.EmployeeId).Contains(item))
                    {
                        list.Add(new RoleEmployeeEntity()
                        {
                            CreateTime = dt,
                            EmployeeId = item,
                            RoleId=request.RoleId,
                            UpdateTime=dt,
                        });
                    }
                }
                if (list.Count > 0) 
                {
                    await _context.RoleEmployee.AddRangeAsync(list);
                    await _context.SaveChangesAsync();
                }
                return JsonResult.Success();
            }
            catch (Exception ex)
            {
                return JsonResult.Error(message: "系统错误");
            }
        }


        /// <summary>
        /// 删除角色员工
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public async Task<JsonResponse> DeleteRoleEmployee(DeleteRoleEmployeeRequest request)
        {
            try
            {
                if (request == null || request.EmployeeIdList == null || request.EmployeeIdList.Count() == 0) return JsonResult.Error(message: "参数错误");

                var roleEmployee = await _context.RoleEmployee.Where(m => m.RoleId == request.RoleId && request.EmployeeIdList.Contains(m.EmployeeId)).ToListAsync();
                if (roleEmployee.Count > 0) 
                {
                    _context.RoleEmployee.RemoveRange(roleEmployee);
                    await _context.SaveChangesAsync();
                }
                return JsonResult.Success();
            }
            catch (Exception ex)
            {
                return JsonResult.Error(message: "系统错误");
            }
        }

        /// <summary>
        /// 递归构建菜单
        /// </summary>
        /// <param name="list"></param>
        /// <param name="model"></param>
        /// <returns></returns>
        private RoleSelectedMenuDto BuildTreeMenu(List<RoleSelectedMenuDto> list, RoleSelectedMenuDto model)
        {
            model.Children = list.Where(m => m.ParentId == model.MenuId).OrderByDescending(p => p.Sort).ToList();
            if (model.Children != null && model.Children.Count() != 0)
            {
                for (int i = 0; i < model.Children.Count(); i++)
                {
                    var child = model.Children[i];
                    child = BuildTreeMenu(list, child);
                }
            }
            return model;
        }

    }
}
